// Copyright (C) 2003 IFOnlyRT Project.

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License 2.0 for more details.

// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/

// Official SVN repository and contact information can be found at
// http://code.google.com/p/ifonlyrt/

#include <iostream>

#include "../../Basics/CVector3.tpp"
#include "ErrorHandler.hpp"

int CVector3_TestAll();
int CVector3_TestStaticsMembers();
int CVector3_TestConstructors();
int CVector3_TestPublicMethods();
int CVector3_TestStaticMethods();

using namespace std;

int CVector3_TestAll()
{
	cout << "::CVector3 - Début des tests ..." << endl;

	if(CVector3_TestStaticsMembers() != 0) return ThrowError("	::CVector3 - Erreur dans le test des membres statiques !");
	if(CVector3_TestConstructors() != 0) return ThrowError("	::CVector3 - Erreur dans le test des constructeurs !");
	if(CVector3_TestPublicMethods() != 0) return ThrowError("	::CVector3 - Erreur dans le test des méthodes publiques !");
	if(CVector3_TestStaticMethods() != 0) return ThrowError("	::CVector3 - Erreur dans le test des méthodes statiques !");

	cout << "::CVector3 - OK" << endl << endl;

	return 0;
}

int CVector3_TestStaticsMembers()
{
	cout << "	::CVector3 - Test des membres statiques..." << endl;

	if(CVector3<double>::Zero != CVector3<double>(0, 0, 0)) return -1;
	if(CVector3<double>::One != CVector3<double>(1, 1, 1)) return -1;
	if(CVector3<double>::Up != CVector3<double>(0, 1, 0)) return -1;
	if(CVector3<double>::Down != CVector3<double>(0, -1, 0)) return -1;
	if(CVector3<double>::Right != CVector3<double>(1, 0, 0)) return -1;
	if(CVector3<double>::Left != CVector3<double>(-1, 0, 0)) return -1;
	if(CVector3<double>::Backward != CVector3<double>(0, 0, 1)) return -1;
	if(CVector3<double>::Forward != CVector3<double>(0, 0, -1)) return -1;

	cout << "	::CVector3 - Membres statiques : OK" << endl;

	return 0;
}

int CVector3_TestConstructors()
{
	cout << "	::CVector3 - Test des constructeurs..." << endl;

	CVector3<double> V;
	if(V.X != 0 || V.Y != 0 || V.Z != 0) return -1;

	V = CVector3<double>(1, 2, 3);
	if(V.X != 1 || V.Y != 2 || V.Z != 3) return -1;

	V = CVector3<double>(666);//!!!!
	if(V.X != 666 || V.Y != 666 || V.Z != 666) return -1;

	CVector3<double> V2(V);
	if(V2.X != 666 || V2.Y != 666 || V2.Z != 666) return -1;

	cout << "	::CVector3 - Constructeurs : OK" << endl;

	return 0;
}

int CVector3_TestPublicMethods()
{
	cout << "	::CVector3 - Test des méthodes publiques..." << endl;

	CVector3<double> V(3, 3, 3);

	if(V.GetModulus() != sqrt(3*9)) return -1;
	if(V.GetSquaredModulus() != 3*9) return -1;

	CVector3<double> V2 = V.GetNormalized();
	if(V2.X != 3.0 / sqrt(3*9) || V2.Y != 3.0 / sqrt(3*9) || V2.Z != 3.0 / sqrt(3*9)) return -1;

	V.Normalize();
	if(V != V2) return -1;

	cout << "	::CVector3 - Méthodes publiques : OK" << endl;

	return 0;
}


int CVector3_TestStaticMethods()
{
	cout << "	::CVector3 - Test des méthodes statiques..." << endl;

	CVector3<double> V(3, 3, 3);
	CVector3<double> V2(1, 2, 3);

	if(CVector3<double>::Dot(V,V) != V.GetSquaredModulus()) return -1;
	if(CVector3<double>::Cross(V,V2) != CVector3<double>(3, -6, 3)) return -1;

	cout << "	::CVector3 - Méthodes statiques : OK" << endl;

	return 0;
}
